package com.ktwlsoft.archivemanage.domain.business.businessService;

import com.google.common.collect.Lists;
import com.ktwlsoft.archivemanage.config.exception.ResultException;
import com.ktwlsoft.archivemanage.domain.business.repositoryService.*;
import com.ktwlsoft.archivemanage.domain.dao.entity.*;
import com.ktwlsoft.archivemanage.payload.Result;
import com.ktwlsoft.archivemanage.payload.ResultType;
import com.ktwlsoft.archivemanage.payload.annualReport.AnnualReportAddRequest;
import com.ktwlsoft.archivemanage.payload.annualReport.AnnualReportUpdateRequest;
import com.ktwlsoft.archivemanage.payload.annualReport.AnnualReportVerifyRequest;
import com.ktwlsoft.archivemanage.payload.annualReport.ReportResponse;
import com.ktwlsoft.archivemanage.payload.exception.BusinessException;
import com.ktwlsoft.archivemanage.payload.operationLog.SaveLogRequest;
import com.ktwlsoft.archivemanage.payload.unitArchive.UnitArchivesAddRequest;
import com.ktwlsoft.archivemanage.payload.unitArchive.UnitArchivesUpdateRequest;
import com.ktwlsoft.archivemanage.service.security.UserPrincipal;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;

@Service
public class AnnualReportBusinessService {

    private AnnualReportRepositoryService annualReportRepositoryService;

    private UnitArchivesRepositoryService unitArchivesRepositoryService;

    private InforConstRepositoryService inforConstRepositoryService;

    private ArchiveUnitRepositoryService archiveUnitRepositoryService;

    private final UnitArchiveManageRepositoryService unitArchiveManageRepositoryService;

    private final NotifyMessageScheduleTask notifyMessageScheduleTask;

    private final ReportLogRepositoryService reportLogRepositoryService;

    private final ImgsService imgsService;

    private final NotifyMessageRepositoryService notifyMessageRepositoryService;

    /**账号业务层接口实现类*/
    private final AccountRepositoryService accountRepositoryService;

    public AnnualReportBusinessService(AnnualReportRepositoryService annualReportRepositoryService,
                                       UnitArchivesRepositoryService unitArchivesRepositoryService,
                                       InforConstRepositoryService inforConstRepositoryService,
                                       ArchiveUnitRepositoryService archiveUnitRepositoryService, UnitArchiveManageRepositoryService unitArchiveManageRepositoryService, NotifyMessageScheduleTask notifyMessageScheduleTask, ReportLogRepositoryService reportLogRepositoryService, ImgsService imgsService, NotifyMessageRepositoryService notifyMessageRepositoryService, AccountRepositoryService accountRepositoryService) {
        this.annualReportRepositoryService = annualReportRepositoryService;
        this.unitArchivesRepositoryService = unitArchivesRepositoryService;
        this.inforConstRepositoryService = inforConstRepositoryService;
        this.archiveUnitRepositoryService = archiveUnitRepositoryService;
        this.unitArchiveManageRepositoryService = unitArchiveManageRepositoryService;
        this.notifyMessageScheduleTask = notifyMessageScheduleTask;
        this.reportLogRepositoryService = reportLogRepositoryService;
        this.imgsService = imgsService;
        this.notifyMessageRepositoryService = notifyMessageRepositoryService;
        this.accountRepositoryService = accountRepositoryService;
    }

    /**
     * @param businessId 业务单号
     * @return Result
     * @description 年度报送详情查询
     */
    public Result findOne(Long businessId) {
        if (businessId == null) {
            return Result.body(null, ResultType.BUSINESS_ERROR).withMessage("年度报送数据不存在");
        }
        ReportDetail reportDetail = annualReportRepositoryService.findAnnualReportInfo(businessId);
        Map<String, Object> data = new HashMap();
        data.put("businessId", businessId);
        List<Map<String, Object>> unitArchivesList = unitArchivesRepositoryService.findUnitArchivesList(data);
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("unitArchives", unitArchivesList);
        //创建人电话
        if(reportDetail != null && reportDetail.getCreatorId() != null) {
            Account account = accountRepositoryService.getById(reportDetail.getCreatorId());
            if(account != null){
                reportDetail.setCreatorPhone(account.getTeleNum());
            }
        }
        resultMap.put("inforConst", reportDetail);
        Imgs imgs = new Imgs();
        imgs.setBusinessId(businessId);
        imgs.setBusinessType("YEARREPORTIMG");
        resultMap.put("imgs",imgsService.findList(imgs));
        return Result.body(resultMap, ResultType.BUSINESS_SUCCESS);
    }

    /**
     * @param request
     * @return request
     * @description 年度报送数据新增
     */
    @Transactional(rollbackFor = Exception.class)
    public Result addAnnualReport(AnnualReportAddRequest request) {
        if (request.getUnitId() == null) {
            return Result.body(null, ResultType.CHECK_ERROR).withMessage("立档单位信息不存在");
        }
        Account account = UserPrincipal.getCurrentUser();
        if(account == null){
            account = new Account();
        }
        List<UnitArchivesAddRequest> list = request.getUnitArchivesList();
        Report report = new Report();
        /**生成年度报送单号(当前年度+档案单位编号+该单位报送顺序号)**/
        String reportId = generateReportId(request.getReportYear().toString(), request.getUnitId());
        report.setReportId(reportId);
        report.setUnitId(request.getUnitId());
        report.setWriteDate(request.getReportYear());
        ReportDetail reportDetail = annualReportRepositoryService.findAnnualReportDetail(report);
        /**验证是否已添加当前选择年度的年度报送信息**/
        if (reportDetail != null) {
            Map<String, Object> data = new HashMap<>();
            data.put("businessId", reportDetail.getId());
            data.put("unitId", request.getUnitId());
            List<Map<String, Object>> unitArchivesList = unitArchivesRepositoryService.findUnitArchivesList(data);
            if (unitArchivesList != null && unitArchivesList.size() > 0) {
                return Result.body(request.getReportYear(), ResultType.BUSINESS_ERROR).withMessage("当前年度已添加报送数据");
            }
        }
        BeanUtils.copyProperties(request, report);
        /**添加年度报送信息**/
        //report.setWritter(request.getWritter());
        report.setState("WAIT");
        report.setCompareConfirm(false);
        report.setCreatedAt(new Date());
        report.setCreator(account.getRealName());
        report.setCreatorId(account.getId());
        try {
            annualReportRepositoryService.addAnnualReportInfo(report);
            if (list != null && list.size() > 0) {
                /**批量增加室藏档案信息**/
                for (UnitArchivesAddRequest unitArchivesAddRequest : list) {
                    UnitArchives unitArchives = new UnitArchives();
                    BeanUtils.copyProperties(unitArchivesAddRequest, unitArchives);
                    unitArchives.setBusinessId(report.getId());
                    unitArchives.setBusinessFrom("report");
                    unitArchives.setUnitId(report.getUnitId());
                    unitArchives.setVerifyState("WAIT");
                    unitArchivesRepositoryService.addUnitArchives(unitArchives);
                }
            }
            notifyMessageScheduleTask.addAnnualReportWeb(report);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ResultException(e.getMessage());
        }
        try {
            if(request.getImgs() != null && request.getImgs().size() > 0){
                List<Imgs> saveImg = Lists.newArrayList();
                List<Imgs> deleteImg = Lists.newArrayList();
                request.getImgs().forEach(value ->{
                    Imgs imgs = new Imgs();
                    BeanUtils.copyProperties(value, imgs);
                    if(value.getType() == 1){
                        saveImg.add(imgs);
                    }else if(value.getType() == 2){
                        deleteImg.add(imgs);
                    }
                });
                if(saveImg.size() > 0){
                    imgsService.manySave(report.getId(), "YEARREPORTIMG", saveImg);
                }
                if (deleteImg.size() > 0) {
                    for (Imgs imgs : deleteImg) {
                        ImgUploadService.deleteById(imgs.getId());
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ResultException(e.getMessage());
        }
        reportLogRepositoryService.saveLog(ReportLog.OperationType.COMMIT_REPORT, report.getId());
        return Result.ok(report.getId());
    }

    /**
     * @param request
     * @return Result
     * @description 年度报送数据更新
     */
    @Transactional(rollbackFor = Exception.class)
    public Result updateAnnualReport(AnnualReportUpdateRequest request) {
        Long businessId = request.getBusinessId();
        if (businessId == null) {
            return Result.body(null, ResultType.CHECK_ERROR).withMessage("年度报送数据不存在");
        }
        List<UnitArchivesUpdateRequest> list = request.getUnitArchivesList();
        try {
            Report report = new Report();
            report.setId(businessId);
            report.setState("WAIT");
            report.setWriteDate(request.getReportYear());
            /**更新年度报送信息·**/
            annualReportRepositoryService.updateAnnualReportInfo(report);
            if (list != null && list.size() > 0) {
                /**批量更新年度报送室藏档案信息**/
                for (UnitArchivesUpdateRequest item : list) {
                    UnitArchives unitArchives = new UnitArchives();
                    BeanUtils.copyProperties(item, unitArchives);
                    unitArchives.setVerifyState("WAIT");
                    unitArchives.setId(item.getArchiveId());
                    //unitArchives.setUnitId(unitId);
                    unitArchives.setBusinessFrom("report");
                    unitArchivesRepositoryService.updateUnitArchives(unitArchives);
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            throw new ResultException(e.getMessage());
        }
        try {
            if(request.getImgs() != null && request.getImgs().size() > 0){
                List<Imgs> saveImg = Lists.newArrayList();
                List<Imgs> deleteImg = Lists.newArrayList();
                request.getImgs().forEach(value ->{
                    Imgs imgs = new Imgs();
                    BeanUtils.copyProperties(value, imgs);
                    if(value.getType() == 1){
                        saveImg.add(imgs);
                    }else if(value.getType() == 2){
                        deleteImg.add(imgs);
                    }
                });
                if(saveImg.size() > 0){
                    imgsService.manySave(businessId, "YEARREPORTIMG", saveImg);
                }
                if (deleteImg.size() > 0) {
                    for (Imgs imgs : deleteImg) {
                        ImgUploadService.deleteById(imgs.getId());
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            throw new ResultException(e.getMessage());
        }
        reportLogRepositoryService.saveLog(ReportLog.OperationType.COMMIT_REPORT, request.getBusinessId());
        return Result.ok(null);
    }

    /**
     * @param request
     * @return Result
     * @description 年度报送数据验证确认
     */
    @Transactional(rollbackFor = Exception.class)
    public Result verifyConfirm(AnnualReportVerifyRequest request) {
        Report oldReport  = annualReportRepositoryService.findAnnualReportDetailById(request.getBusinessId());
        if (oldReport == null) {
            throw new BusinessException("年度报送验证确认，未找到对应的年度报送信息， reportId: " + request.getBusinessId());
        }
        Report report = new Report();
        report.setId(request.getBusinessId());
        report.setState(request.getVerifyAction());
        report.setRemark(request.getRemark());
        report.setInstructorSign(request.getInstructorSign());
        report.setUnitSign(request.getUnitSign());
        report.setUpdateAt(null);
        report.setCreatedAt(null);
        try {
            if ("PASS".equals(request.getVerifyAction())) {
                //check if the same year data exists from manual, if it is then set valid false
                if (!unitArchiveManageRepositoryService.existByUnitAndYear(oldReport.getUnitId(), oldReport.getWriteDate())) {
                    report.setValid(true);
                }
                annualReportRepositoryService.updateAnnualReportInfo(report);
                UnitArchives unitArchives = new UnitArchives();
                unitArchives.setBusinessId(report.getId());
                unitArchives.setVerifyState(request.getVerifyAction());
                unitArchives.setUpdateAt(null);
                unitArchivesRepositoryService.updateUnitArchivesInfo(unitArchives);
                notifyMessageScheduleTask.annualRepostNotPassNotifyMessage(request.getBusinessId(),true);
                reportLogRepositoryService.saveLog(ReportLog.OperationType.VERIFY_PASS, report.getId());
                verifyConfirmNotifyMessage(report,true);
            } else {
                annualReportRepositoryService.updateAnnualReportInfo(report);
                // generate report unpass notifycation
                notifyMessageScheduleTask.annualRepostNotPassNotifyMessage(request.getBusinessId(),false);
                reportLogRepositoryService.saveLog(ReportLog.OperationType.VERIFY_REFUSE, report.getId());
                verifyConfirmNotifyMessage(report,false);
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new ResultException(e.getMessage());
        }
        return Result.body(null, ResultType.BUSINESS_SUCCESS).withMessage("年度报送验证完成");
    }

    /**
      * 新增年度报送验证通知 on 2020/4/20 15:37
      *
      * @param report report
      * @param b true通过,false不通过
      */
    private void verifyConfirmNotifyMessage (Report report,boolean b){
        Report report1 = annualReportRepositoryService.getIReportMapper().getById(report.getId());
        ArchiveUnit unit = archiveUnitRepositoryService.getById(report1.getUnitId());
        OperationRepositoryService.saveLog(new SaveLogRequest(OperationLog.OperationType.VERIFY,
                unit.getUnitName() + report1.getWriteDate() + (b?"年度报送验证通过":"年度报送验证不通过"),
                "年度报送",
                OperationLog.BusinessType.BUSINESS));
    }

    /**
     * 生成年度报送单号(当前年度+档案单位编号+该单位报送顺序号)
     *
     * @param unitId 立档单位id
     * @return String
     */
    private String generateReportId(String reportYear, Long unitId) {
        Integer initialSequenceId = 1;
        StringBuffer stringBuffer = new StringBuffer();
        if (reportYear != null) {
            stringBuffer.append(reportYear.substring(0, 4));
        }
        if (unitId != null) {
            stringBuffer.append(unitId);
        }
        List<ReportResponse> existedList = annualReportRepositoryService.findExistedReportList();
        Collections.sort(existedList);
        /**如果没有已新增的报送单号,新增的年度报送单号后3位从001开始**/
        if (existedList == null || existedList.size() <= 0) {
            stringBuffer.append("00").append(initialSequenceId);
        } else {
            ReportResponse reportResponse = existedList.get(0);
            String reportIdString = reportResponse.getReportId();
            /**如果年度报送单号长度大于22位,取后3位自增**/
            if (reportIdString.length() > 22) {
                String sequenceString = reportIdString.substring(22);
                Integer sequenceInteger = Integer.parseInt(sequenceString);
                Integer nextSequenceInteger = sequenceInteger + 1;
                if (sequenceInteger.intValue() < 10) {
                    stringBuffer.append("00").append(nextSequenceInteger);
                } else if (sequenceInteger < 100) {
                    stringBuffer.append("0").append(nextSequenceInteger);
                } else if (sequenceInteger < 1000) {
                    stringBuffer.append(nextSequenceInteger);
                }
            } else {/**如果长度小于22位,新增的年度报送单号后3位从001开始**/
                stringBuffer.append("00").append(initialSequenceId);
            }
        }
        return stringBuffer.toString();
    }
}
